package com.basic.library.binding.viewadapter.recyclerview;


import androidx.databinding.BindingAdapter;
import androidx.databinding.ObservableArrayList;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import com.basic.library.binding.command.BindingCommand;
import com.basic.library.brvah.MBaseViewHolder;
import com.basic.library.brvah.MSimpleClickListener;
import com.basic.library.brvah.MyBaseMultiItemQuickAdapter;
import com.basic.library.brvah.MyBaseQuickAdapter;
import com.chad.library.adapter.base.BaseQuickAdapter;

import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

import io.reactivex.functions.Consumer;
import io.reactivex.subjects.PublishSubject;
import me.tatarka.bindingcollectionadapter2.LayoutManagers;

/**
 * Created by goldze on 2017/6/16.
 */
public class ViewAdapter {

    /**
     * SwipeRefreshLayout的刷完框消失事件都写在MyBaseQuickAdapter里了,但刷新监听没有（bindEasyAdapter两种都写了）
     * mSimpleClickListener和onItemChildClickListener一般只需要一种，多了容易搞错
     */
    @BindingAdapter(value = {"bindAdapter", "layoutManager", "bindItems", "bindSimpleItemClick", "bindItemChildClick", "setLoadMore"}, requireAll = false)
    public static <T, K extends MBaseViewHolder> void initAdapter(RecyclerView recyclerView
            , BaseQuickAdapter<T, K> adapter
            , LayoutManagers.LayoutManagerFactory layoutManagerFactory
            , ArrayList<T> list
            , MSimpleClickListener mSimpleClickListener
            , BaseQuickAdapter.OnItemChildClickListener listener
            , BaseQuickAdapter.RequestLoadMoreListener loadMoreListener) {
        if (adapter != null && recyclerView.getAdapter() == null)
            try {
                recyclerView.setLayoutManager(layoutManagerFactory.create(recyclerView));
                if (loadMoreListener != null)
                    adapter.setOnLoadMoreListener(loadMoreListener);
                adapter.bindToRecyclerView(recyclerView);
                //没数据的时候不初始化数据，第一次获取真实数据的时候setNewData，可以避免提前setNewData
//                if (list == null) {
//                    list = new ArrayList<>(adapter.getData());
//                }
                if (list instanceof ObservableArrayList) {
                    ((ObservableArrayList) list).addOnListChangedCallback(ListFactory.getListChangedCallback(adapter));
                }
                if (list != null)
                    if (adapter instanceof MyBaseQuickAdapter) {
                        MyBaseQuickAdapter adapter1 = (MyBaseQuickAdapter) adapter;
                        adapter1.initData(list);
                    } else if (adapter instanceof MyBaseMultiItemQuickAdapter) {
                        MyBaseMultiItemQuickAdapter adapter1 = (MyBaseMultiItemQuickAdapter) adapter;
                        adapter1.initData(list);
                    }
                if (mSimpleClickListener != null)
                    recyclerView.addOnItemTouchListener(mSimpleClickListener);
                if (listener != null)
                    adapter.setOnItemChildClickListener(listener);
            } catch (Exception e) {
                e.printStackTrace();
            }
    }

    @BindingAdapter("lineManager")
    public static void setLineManager(RecyclerView
                                              recyclerView, LineManagers.LineManagerFactory lineManagerFactory) {
        recyclerView.addItemDecoration(lineManagerFactory.create(recyclerView));
    }

    @BindingAdapter("itemDecoration")
    public static void setLineManager(RecyclerView recyclerView, RecyclerView.ItemDecoration
            itemDecoration) {
        recyclerView.addItemDecoration(itemDecoration);
    }

    @BindingAdapter(value = {"onScrollChangeCommand", "onScrollStateChangedCommand"}, requireAll = false)
    public static void onScrollChangeCommand(final RecyclerView recyclerView,
                                             final BindingCommand<ScrollDataWrapper> onScrollChangeCommand,
                                             final BindingCommand<Integer> onScrollStateChangedCommand) {
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            private int state;

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (onScrollChangeCommand != null) {
                    onScrollChangeCommand.execute(new ScrollDataWrapper(dx, dy, state));
                }
            }

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                state = newState;
                if (onScrollStateChangedCommand != null) {
                    onScrollStateChangedCommand.execute(newState);
                }
            }
        });

    }

    @SuppressWarnings("unchecked")
    @BindingAdapter({"onLoadMoreCommand"})
    public static void onLoadMoreCommand(final RecyclerView recyclerView,
                                         final BindingCommand<Integer> onLoadMoreCommand) {
        RecyclerView.OnScrollListener listener = new OnScrollListener(onLoadMoreCommand);
        recyclerView.addOnScrollListener(listener);

    }

    @BindingAdapter("itemAnimator")
    public static void setItemAnimator(RecyclerView recyclerView, RecyclerView.ItemAnimator
            animator) {
        recyclerView.setItemAnimator(animator);
    }

    public static class OnScrollListener extends RecyclerView.OnScrollListener {

        private PublishSubject<Integer> methodInvoke = PublishSubject.create();

        private BindingCommand<Integer> onLoadMoreCommand;

        public OnScrollListener(final BindingCommand<Integer> onLoadMoreCommand) {
            this.onLoadMoreCommand = onLoadMoreCommand;
            methodInvoke.throttleFirst(1, TimeUnit.SECONDS)
                    .subscribe(new Consumer<Integer>() {
                        @Override
                        public void accept(Integer integer) throws Exception {
                            onLoadMoreCommand.execute(integer);
                        }
                    });
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
            int visibleItemCount = layoutManager.getChildCount();
            int totalItemCount = layoutManager.getItemCount();
            int pastVisiblesItems = layoutManager.findFirstVisibleItemPosition();
            if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
                if (onLoadMoreCommand != null) {
                    methodInvoke.onNext(recyclerView.getAdapter().getItemCount());
                }
            }
        }

        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
        }


    }

    public static class ScrollDataWrapper {
        public float scrollX;
        public float scrollY;
        public int state;

        public ScrollDataWrapper(float scrollX, float scrollY, int state) {
            this.scrollX = scrollX;
            this.scrollY = scrollY;
            this.state = state;
        }
    }


    /**
     * bindEasyAdapter自动绑定了SwipeRefreshLayout的刷新监听（见方法 setOnRefreshListener）
     * <p>
     * SwipeRefreshLayout的下拉刷新动画在自定义BaseQuickAdapter中写了（见方法 chargeRefresh）；
     * 不过对于搜索框等触发的调用接口无法自动触发下拉动画（主要是下拉开始动画在自定义BaseQuickAdapter找不到合适的触发时机），
     * 这种情况在BaseActivityKt有另外操作（见方法 loading dismiss）
     * <p>
     * mSimpleClickListener和onItemChildClickListener一般只需要一种，多了容易搞错
     *
     * @param recyclerView
     * @param adapterModel
     * @param <T>
     * @param <K>
     */
    @BindingAdapter(value = {"bindEasyAdapter"}, requireAll = true)
    public static <T, K extends MBaseViewHolder> void initEasyAdapter(RecyclerView recyclerView
            , EasyAdapterModel<T, K> adapterModel) {
        BaseQuickAdapter<T, K> adapter = adapterModel.adapter;
        LayoutManagers.LayoutManagerFactory layoutManagerFactory = adapterModel.layoutManagerFactory;
        ArrayList<T> list = adapterModel.initList;
        MSimpleClickListener mSimpleClickListener = adapterModel.mSimpleClickListener;
        BaseQuickAdapter.OnItemChildClickListener listener = adapterModel.onItemChildClickListener;
        BaseQuickAdapter.RequestLoadMoreListener loadMoreListener = adapterModel.loadMoreListener;
        LineManagers.LineManagerFactory lineManagerFactory = adapterModel.lineManagerFactory;
        if (adapter != null && recyclerView.getAdapter() == null)
            try {
                //自动绑定监听
                if (adapterModel.onRefreshListener != null) {
                    setOnRefreshListener(recyclerView, adapterModel.onRefreshListener);
                }
                recyclerView.setLayoutManager(layoutManagerFactory.create(recyclerView));
                if (loadMoreListener != null)
                    adapter.setOnLoadMoreListener(loadMoreListener);
                adapter.bindToRecyclerView(recyclerView);
                if (lineManagerFactory != null)
                    recyclerView.addItemDecoration(lineManagerFactory.create(recyclerView));
                //没数据的时候不初始化数据，第一次获取真实数据的时候setNewData，可以避免提前setNewData
//                if (list == null) {
//                    list = new ArrayList<>(adapter.getData());
//                }
                if (list instanceof ObservableArrayList) {
                    ((ObservableArrayList) list).addOnListChangedCallback(ListFactory.getListChangedCallback(adapter));
                }
                if (list != null)
                    if (adapter instanceof MyBaseQuickAdapter) {
                        MyBaseQuickAdapter adapter1 = (MyBaseQuickAdapter) adapter;
                        adapter1.initData(list);
                    } else if (adapter instanceof MyBaseMultiItemQuickAdapter) {
                        MyBaseMultiItemQuickAdapter adapter1 = (MyBaseMultiItemQuickAdapter) adapter;
                        adapter1.initData(list);
                    }
                if (mSimpleClickListener != null)
                    recyclerView.addOnItemTouchListener(mSimpleClickListener);
                if (listener != null)
                    adapter.setOnItemChildClickListener(listener);
            } catch (Exception e) {
                e.printStackTrace();
            }
    }

    /**
     * SwipeRefreshLayout最多2层，够用了
     */
    public static void setOnRefreshListener(RecyclerView recyclerView, SwipeRefreshLayout.OnRefreshListener onRefreshListener) {
        if (recyclerView != null) {
            if (recyclerView.getParent() instanceof SwipeRefreshLayout)
                ((SwipeRefreshLayout) recyclerView.getParent()).setOnRefreshListener(onRefreshListener);
            else if (recyclerView.getParent().getParent() instanceof SwipeRefreshLayout)
                ((SwipeRefreshLayout) recyclerView.getParent().getParent()).setOnRefreshListener(onRefreshListener);
        }
    }
}
